'use client';

import { type ChangeEvent, type FormEvent, useEffect, useState } from 'react';
import { useMutation } from '@tanstack/react-query';
import type { IDifference, IPermissionDetails } from '@/interfaces';
import diff from 'microdiff';
import { updatePermission } from '@/services/api';
import type { TPermissionMethod, TPermissionType } from '@/types';
import useToast from '@/hooks/useToast';
import { getDiffData } from '@/lib/tool';
import Box from '@/app/[locale]/admin/common/box';
import Spinner from '@/app/[locale]/component/spinner/spinner';
import type { PrefixedTTranslatedFields } from '@/lib/dictionaries';

export default function UpdatePermissionInfo({
  source,
  translatedFields,
}: {
  source: IPermissionDetails;
  translatedFields: PrefixedTTranslatedFields<'permissionAdminPage'>;
}) {
  const { show } = useToast();
  const [form, setForm] = useState<{
    name?: string;
    alias?: string;
    overview?: string;
    method?: TPermissionMethod;
    type?: TPermissionType;
    caseInsensitive?: boolean;
    sort?: number;
    categoryId?: string;
    categoryName?: string;
  }>({
    name: source.basic.name,
    alias: source.basic.alias ?? '',
    overview: source.basic.overview ?? '',
    method: source.basic.method,
    type: source.basic.type,
    caseInsensitive: source.basic.caseInsensitive,
    sort: source.basic.sort,
    categoryId: source.basic.categoryId ?? '',
    categoryName: source.basic.categoryName ?? '',
  });
  const [differenceData, setDifferenceData] = useState<IDifference[]>([]);
  const [isDisabledSave, setIsDisabledSave] = useState(true);

  const updatePermissionMutation = useMutation(updatePermission);

  useEffect(() => {
    const diffData = diff(
      {
        name: source.basic.name,
        alias: source.basic.alias ?? '',
        overview: source.basic.overview ?? '',
        method: source.basic.method,
        type: source.basic.type,
        caseInsensitive: source.basic.caseInsensitive,
        sort: source.basic.sort,
        categoryId: source.basic.categoryId ?? '',
        categoryName: source.basic.categoryName ?? '',
      },
      form,
    );
    setDifferenceData(diffData);
    setIsDisabledSave(diffData.length === 0);
  }, [form, source]);

  async function onClickSave(e: FormEvent<HTMLFormElement>) {
    try {
      e.preventDefault();
      e.stopPropagation();

      checkForm();

      const id = source.basic.id;
      const data = getDiffData(differenceData);
      await updatePermissionMutation.mutateAsync({
        id,
        data,
      });

      show({
        type: 'SUCCESS',
        message: translatedFields.operate.updateCompleted,
      });
    } catch (e) {
      updatePermissionMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    } finally {
      setDifferenceData([]);
    }
  }

  function checkForm() {
    const { name } = form;

    if (!name) {
      throw translatedFields.tip.requiredPermissionName;
    }
  }

  function onChangeForm(
    e: ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>,
  ) {
    const name = e.target.name;
    const value = e.target.value;

    if (name === 'caseInsensitive') {
      setForm({ ...form, caseInsensitive: value === 'true' });
    } else if (name === 'sort') {
      setForm({ ...form, sort: parseInt(value) });
    } else {
      setForm({ ...form, [name]: value });
    }
  }

  return (
    <Box>
      <form onSubmit={onClickSave} className="vstack gap-4">
        <div className="row">
          <div className="col">
            <div>
              <label className="form-label">
                {translatedFields.properties.name}
              </label>
              <textarea
                className="form-control"
                name="name"
                value={form.name}
                onChange={onChangeForm}
                aria-describedby="name"
                rows={1}
                placeholder={translatedFields.tip.namePlaceholder}
              />
            </div>
          </div>
          <div className="col">
            <div>
              <label className="form-label">
                {translatedFields.properties.alias}
              </label>
              <input
                type="text"
                className="form-control"
                name="alias"
                value={form.alias}
                onChange={onChangeForm}
                aria-describedby="alias"
                placeholder={translatedFields.tip.aliasPlaceholder}
              />
            </div>
          </div>
        </div>

        <div className="row">
          <div className="col">
            <div>
              <label className="form-label">
                {translatedFields.properties.overview}
              </label>
              <input
                type="text"
                className="form-control"
                name="overview"
                value={form.overview}
                onChange={onChangeForm}
                aria-describedby="overview"
                placeholder={translatedFields.tip.overviewPlaceholder}
              />
            </div>
          </div>
          <div className="col">
            <div>
              <label className="form-label">
                {translatedFields.properties.method}
              </label>
              <select
                name="method"
                value={form.method}
                onChange={onChangeForm}
                className="form-select"
                aria-label="method"
                placeholder={translatedFields.tip.methodPlaceholder}
              >
                <option value="GET">GET</option>
                <option value="HEAD">HEAD</option>
                <option value="POST">POST</option>
                <option value="PUT">PUT</option>
                <option value="PATCH">PATCH</option>
                <option value="DELETE">DELETE</option>
                <option value="OPTIONS">OPTIONS</option>
                <option value="TRACE">TRACE</option>
              </select>
            </div>
          </div>
        </div>

        <div className="row">
          <div className="col">
            <div>
              <label className="form-label">
                {translatedFields.properties.type}
              </label>
              <select
                name="type"
                value={form.type}
                onChange={onChangeForm}
                className="form-select"
                aria-label="type"
                placeholder={translatedFields.tip.typePlaceholder}
              >
                <option value="ANT">{translatedFields.properties.path}</option>
                <option value="REGEX">
                  {translatedFields.properties.regex}
                </option>
              </select>
            </div>
          </div>
          <div className="col">
            <div>
              <label className="form-label">
                {translatedFields.properties.caseInsensitive}
              </label>
              <select
                name="caseInsensitive"
                value={form.caseInsensitive + ''}
                onChange={onChangeForm}
                className="form-select"
                aria-label="caseInsensitive"
                placeholder={translatedFields.tip.caseInsensitivePlaceholder}
              >
                <option value="false">false</option>
                <option value="true">true</option>
              </select>
            </div>
          </div>
        </div>

        <div className="row">
          <div className="col">
            <div>
              <label className="form-label">
                {translatedFields.properties.sort}
              </label>
              <input
                type="number"
                min={0}
                className="form-control"
                name="sort"
                value={form.sort}
                onChange={onChangeForm}
                aria-describedby="sort"
                placeholder={translatedFields.tip.sortPlaceholder}
              />
            </div>
          </div>
          <div className="col">
            <div>
              <label className="form-label">
                {translatedFields.properties.categoryId}
              </label>
              <textarea
                className="form-control"
                name="categoryId"
                value={form.categoryId}
                onChange={onChangeForm}
                aria-describedby="categoryId"
                rows={1}
                placeholder={translatedFields.tip.categoryIdPlaceholder}
              />
            </div>
          </div>
        </div>

        <div className="row">
          <div className="col">
            <div>
              <label className="form-label">
                {translatedFields.properties.categoryName}
              </label>
              <input
                type="text"
                className="form-control"
                name="categoryName"
                value={form.categoryName}
                onChange={onChangeForm}
                aria-describedby="categoryName"
                placeholder={translatedFields.tip.categoryNamePlaceholder}
              />
            </div>
          </div>
        </div>

        <button
          type="submit"
          disabled={updatePermissionMutation.isLoading || isDisabledSave}
          className="btn btn-success col col-lg-2 my-4"
        >
          {updatePermissionMutation.isLoading && <Spinner classs="me-2" />}
          {translatedFields.operate.update}
        </button>
      </form>
    </Box>
  );
}
